﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace GraphicsEditor
{
    class FillTool : DrawingTool
    {
        public FillTool()
        {
            pixelDown = new Point(0, 0);
            pixelUp = new Point(0,0);
        }
        private Color dataToColor(PixelData data)
        {
            return Color.FromArgb(data.alpha, data.red, data.green, data.blue);
        }
        private PixelData colorToData(Color color)
        {
            PixelData data = new PixelData();
            data.alpha = color.A;
            data.red = color.R;
            data.blue = color.B;
            data.green = color.G;
            return data;
        }
        private Bitmap bucketFill(Point start, Bitmap image)
        {
            List<Point> paintQueue = new List<Point>();
            UnsafeBitmap bmp = new UnsafeBitmap(image);
            bmp.LockBitmap();
            Color targetColor = dataToColor(bmp.GetPixel(start.X, start.Y));
            Color replaceColor = ToolBox.selectedColor ;
            PixelData newColor = new PixelData();
            newColor.alpha = replaceColor.A;
            newColor.red = replaceColor.R;
            newColor.blue = replaceColor.B;
            newColor.green = replaceColor.G;


            if (targetColor.ToArgb() == replaceColor.ToArgb())
            {
                return image ;
            }
            paintQueue.Add(start);
            for (int i = 0; i < paintQueue.Count; ++i)
            {
                //bmp.LockBitmap();
                Point currentPoint = paintQueue[i];
                if (dataToColor(bmp.GetPixel(currentPoint.X, currentPoint.Y)) == targetColor)
                {
                    Point west = currentPoint;
                    Point east = new Point(currentPoint.X + 1, currentPoint.Y);
                    while (west.X >= 0 && dataToColor(bmp.GetPixel(west.X, west.Y)) == targetColor)
                    {
                        bmp.SetPixel(west.X, west.Y, newColor);
                        Point north = new Point(west.X, west.Y - 1);
                        if (north.Y >= 0 && dataToColor(bmp.GetPixel(north.X, north.Y)) == targetColor)
                        {
                            paintQueue.Add(north);
                        }
                        Point south = new Point(west.X, west.Y + 1);
                        if (south.Y < bmp.Bitmap.Height && dataToColor(bmp.GetPixel(south.X, south.Y)) == targetColor)
                        {
                            paintQueue.Add(south);
                        }
                        west.X --;
                    }

                    while (east.X < bmp.Bitmap.Width && dataToColor(bmp.GetPixel(east.X, east.Y)) == targetColor )
                    {
                        bmp.SetPixel(east.X, east.Y, newColor);
                        Point north = new Point(east.X, east.Y - 1);
                        if (north.Y >= 0 && dataToColor(bmp.GetPixel(north.X, north.Y)) == targetColor)
                        {
                            paintQueue.Add(north);
                        }
                        Point south = new Point(east.X, east.Y + 1);
                        if (south.Y < bmp.Bitmap.Height && dataToColor(bmp.GetPixel(south.X, south.Y)) == targetColor)
                        {
                            paintQueue.Add(south);
                        }
                        east.X++;
                    }
                    
                }
                //bmp.UnlockBitmap();
            }
            bmp.UnlockBitmap();
            return bmp.Bitmap;


        }
        public override void setMouseDown(Point mouseLoc, PictureBoxAdvance pictureWindow)
        {
            pictureWindow.Image = bucketFill(getPixelPositionUsingMouse(mouseLoc, pictureWindow), new Bitmap(pictureWindow.Image));
        }
        public override void mouseMoved(Point mouseLoc, PictureBoxAdvance pictureWindow, ImageForm imageform, bool mouseDown)
        {

        }
        public override void paintSelection(Graphics gfx, PictureBoxAdvance pictureWindow, bool zoom)
        {

        }
    }
}
